#include "tcpconnection.hpp"
#include <sstream>
#include "logger.h"
namespace moqi
{
TcpConnection::TcpConnection(int fd)
:_sock(fd),
_sockio(fd),
_localAddr(getLocalAddr()),
_peerAddr(getPeerAddr())
{

}
TcpConnection::~TcpConnection()
{

}

void TcpConnection::send(const string& msg)const
{
    _sockio.sendn(msg.c_str(), msg.size());
}

string TcpConnection::recv()
{
    char buff[65536] = {0};
    int ret = _sockio.recvLine(buff, sizeof(buff));
    return string(buff, ret);
}

void TcpConnection::shutdown()
{
    _sock.shutdownWrite();
}

bool TcpConnection::isClosed()const
{
    char buff[20] = {0};
    return _sockio.recvPeek(buff, sizeof(buff)) == 0;
}

string TcpConnection::status()const
{
    std::ostringstream oss;
    oss<<"[ " << _localAddr.ip() << " : " << _localAddr.port() <<" ---> "
        << _peerAddr.ip() << " : " << _peerAddr.port() << " ]";
    return oss.str();
}

void TcpConnection::handleNewConnectionCallback()
{
    if(_onConnecton)
    {
        _onConnecton(shared_from_this());
    }
}

void TcpConnection::handleMessageCallback()
{
    if(_onMessage)
    {
        _onMessage(shared_from_this());
    }
}

void TcpConnection::handleCloseCallback()
{
    if(_onClose)
    {
        _onClose(shared_from_this());
    }
}




InetAddress TcpConnection::getLocalAddr()
{
    address_IPv4 addr;
    socklen_t len = sizeof(addr);
    memset(&addr, 0, len);
    int ret = getpeername(_sock.fd(),(struct sockaddr*)&addr, &len);
    if(ret < 0)
    {
        LOG_ERROR("getLocalAddr");
    }
    return InetAddress(addr);
}

InetAddress TcpConnection::getPeerAddr()
{
    address_IPv4 addr;
    socklen_t len = sizeof(addr);
    memset(&addr, 0, len);
    int ret = getsockname(_sock.fd(),(struct sockaddr*)&addr, &len);
    if(ret < 0)
    {
        LOG_ERROR("getPeerAddr");
    }
    return InetAddress(addr);
}

}//end of namespace moqi
